package com.cqupt.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cqupt.common.log.annotation.OperationLog;
import com.cqupt.pojo.Problem;
import com.cqupt.pojo.ResponseMessage;
import com.cqupt.service.KnowledgeService;
import com.cqupt.service.TriggerService;
import com.cqupt.utils.APIUtils;
import com.cqupt.utils.DateUtils;
import com.cqupt.utils.RegularMatcher;
import com.cqupt.utils.TextUtils;
import org.apache.poi.hssf.record.DVALRecord;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

@CrossOrigin
@Controller
@RequestMapping("trigger")
@ResponseBody
public class TriggerController {
    @Autowired
    private TriggerService triggerService;
    @Autowired
    private KnowledgeService knowledgeService;

    /**
     * 根据监控项id获取所有触发器列表
     * @param itemid
     * @return
     */
    @RequestMapping("getAllTriggersByItemid")
    public ResponseMessage getAllTriggerBtItemid(@RequestParam(value = "itemid") String itemid){
        // 获取令牌
        String token = APIUtils.getToken();
        ResponseMessage responseMessage = new ResponseMessage();
        List<Map<String,Object>> triggers = triggerService.getAllTriggersByItemid(itemid,token);
        // 封装返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("triggers", triggers);
        responseMessage.setContent(result);
        return responseMessage;
    }

    /**
     * 根据主机id获取所有触发器
     * @param hostid 主机id
     * @return
     */
    @RequestMapping("getAllTriggersByHostid")
    public ResponseMessage getAllTriggerBtHostid(@RequestParam(value = "hostid") String hostid){
        String token = APIUtils.getToken();
        ResponseMessage responseMessage = new ResponseMessage();
        List<Map<String,Object>> triggers = triggerService.getAllTriggersByHostid(hostid,token);
        //封装返回结果
        ResponseMessage temp = packDataToResponseMessage(responseMessage, triggers);
        return temp;
    }

    /**
     * 封装结果到ResponseMessage
     * @param responseMessage
     * @param resMap
     * @return
     */
    public ResponseMessage packDataToResponseMessage(ResponseMessage responseMessage, List<Map<String, Object>> resMap){
        Map<String, Object> resultMap = new HashMap<String, Object>() {{
            List<Map<String, Object>> triggers = new ArrayList<Map<String, Object>>();
            for (Map<String,Object> map : resMap) {
                triggers.add(new HashMap<String,Object>(){{
                    put("expression", map.get("expression"));
                    /*
                        0 - (default 默认) not classified; 未分类；
                        1 - information; 信息；
                        2 - warning; 警告；
                        3 - average; 一般严重；
                        4 - high; 严重；
                        5 - disaster. 灾难。
                     */
                    if ("0".equals(map.get("priority"))) {
                        put("priority", "未分类");
                    }else if ("1".equals(map.get("priority"))) {
                        put("priority", "信息");
                    }else if ("2".equals(map.get("priority"))) {
                        put("priority", "警告");
                    }else if ("3".equals(map.get("priority"))) {
                        put("priority", "一般严重");
                    }else if ("4".equals(map.get("priority"))) {
                        put("priority", "严重");
                    }else if ("5".equals(map.get("priority"))) {
                        put("priority", "灾难");
                    }
                    /*
                        0 - (default 默认) OK; 正常；
                        1 - problem. 故障。
                     */
                    if ("0".equals(map.get("value"))) {
                        put("value", "正常");
                    }else if ("1".equals(map.get("value"))) {
                        put("value", "故障");
                    }
                    /*
                        0 - (default 默认) enabled; 启用；
                        1 - disabled. 禁用。
                     */
                    if ("0".equals(map.get("status"))) {
                        put("status", "启用");
                    }else if ("1".equals(map.get("status"))) {
                        put("status", "禁用");
                    }
                    put("templateid", map.get("templateid"));
                    put("dependencies", map.get("dependencies"));
                    put("description", map.get("description"));
                    put("opdata", map.get("opdata"));
                    put("triggerid", map.get("triggerid"));
                }});
            }
            put("triggers", triggers);
            put("total", triggers.size());
        }};
        responseMessage.setStatus(true);
        responseMessage.setContent(resultMap);
        return responseMessage;
    }
    /**
    * @Description //创建触发器告警项
    * @Date 9:41 2020/12/14
    * @Param [triggerParams]名称、表达式、严重性、状态（启用）、描述、是否允许手动关闭
    **/
    @OperationLog(level = "信息", object = "告警项", operationType = "新增")
    @RequestMapping("createTrigger")
    public ResponseMessage createTrigger(@RequestBody Map<String,Object> triggerParams){
        ResponseMessage responseMessage = new ResponseMessage();

        // 重名不可重复添加
        Map<String,Object> resultMap = new HashMap<>();
        String description = triggerParams.get("description").toString();
        String hostId = triggerParams.get("hostid").toString();


        if (triggerService.isExistTrigger(description, hostId)) {
            responseMessage.setStatus(false);
            responseMessage.setErrorCode("重名，添加失败！");
            resultMap.put("createFlag","重名，添加失败！");
            resultMap.put("log_objectName",triggerParams.get("description").toString());
            responseMessage.setContent(resultMap);
            return responseMessage;
        }

        // 获取级别
        Integer priority = Integer.parseInt(triggerParams.get("priority").toString());
        // 获取状态
        Integer status = Integer.parseInt(triggerParams.get("status").toString());
        // 是否可以手动关闭
        Integer manual_close = Integer.parseInt(triggerParams.get("manual_close").toString());
        Map<String, Object> triggerParamsMap = new HashMap<String, Object>() {{
            // 触发器描述
            put("description",triggerParams.get("description").toString());
            // 触发器表达式
            put("expression",triggerParams.get("expression").toString());
            // 触发器级别
            put("priority",priority);
            // 触发器状态
            put("status",status);
            // 触发器名称
            put("comments",triggerParams.get("comments").toString());
            // 触发器手动关闭
            put("manual_close",manual_close);
        }};
        Map<String, Object> createFlag = triggerService.createTrigger(triggerParamsMap);
        // 获取标志量
        boolean flag = (boolean) createFlag.get("flag");

        // 转换为公共键值
        String coomonKey = RegularMatcher.RE_Matcher(triggerParams.get("expression").toString());
        String problemName = triggerParams.get("description").toString();
        String comments = triggerParams.get("comments").toString();


        resultMap.put("log_objectName",triggerParams.get("description").toString());
        if (flag){
            // 将自定义触发器写入数据库中
            Problem problem = new Problem(problemName,coomonKey,comments);
            // 新创建触发器写入数据库中
            boolean flagOfProblem = triggerService.insertProblemIntoDatabase(problem);
            if (flagOfProblem) {
                responseMessage.setStatus(true);
                resultMap.put("log_description",triggerParams.get("expression").toString());
                resultMap.put("createFlag","添加成功");
                resultMap.put("triggerid",createFlag.get("message"));
            }
            else{
                responseMessage.setStatus(false);
                responseMessage.setErrorCode("");
                resultMap.put("createFlag",createFlag.get("message"));
            }
        }else{
            responseMessage.setStatus(false);
            responseMessage.setErrorCode("");
            resultMap.put("createFlag",createFlag.get("message"));
        }
        responseMessage.setContent(resultMap);
        return responseMessage;
    }
    /**
    * @Description //删除告警项
    * @Date 9:44 2020/12/14
    * @Param triggerId
    **/
    @OperationLog(level = "信息", object = "告警项", operationType = "删除")
    @RequestMapping("deleteTrigger")
    public ResponseMessage deleteTrigger(@RequestBody Map<String,Object> params){
        ResponseMessage responseMessage = new ResponseMessage();
        // 获取触发器id
        List<String> triggerIds = (List<String>) params.get("triggerIds");
        // 获取触发器名称
        List<String> triggerNames = (List<String>) params.get("triggerNames");
        // 根据id删除触发器
        Map<String, Object> returnNews = triggerService.deleteTrigger(triggerIds);
        boolean flag = (boolean) returnNews.get("flag");
        String message = returnNews.get("message").toString();
        Map<String, Object> resultMap = new HashMap<>();
        if (triggerIds.size() == 1){
            resultMap.put("log_objectName",triggerNames.get(0));
        }else {
            resultMap.put("log_objectName",triggerNames.toString());
        }
        if (flag){
            responseMessage.setStatus(true);
            resultMap.put("message",message);
            resultMap.put("log_description","");
        }else {
            responseMessage.setStatus(false);
            responseMessage.setErrorCode("内置告警项不能删除！");
            resultMap.put("error",message);
        }
        responseMessage.setContent(resultMap);
        return responseMessage;
    }

    /**
    * @param triggerid
    * @param status
    * @return com.cqupt.pojo.ResponseMessage
    * @Description 开启或关闭单个告警项
    * @date 2020/12/14 16:02
    */
    @OperationLog(level = "信息", object = "告警项", operationType = "启用")
    @RequestMapping("enableTrigger")
    public ResponseMessage enableTrigger(@RequestParam(value = "triggerid") String triggerid,
                                          @RequestParam(value = "status") String status,
                                         @RequestParam(value = "name") String name){
        // 更新告警项状态
        Map<String,Object> result = triggerService.updateTrigger(triggerid,status);

        ResponseMessage responseMessage = new ResponseMessage();
        result.put("log_objectName",name);
        result.put("log_description","启用"+name);
        responseMessage.setContent(result);
        responseMessage.setStatus(true);
        return responseMessage;
    }

    /**
     * @param triggerid
     * @param status
     * @return com.cqupt.pojo.ResponseMessage
     * @Description 开启或关闭单个告警项
     * @date 2020/12/14 16:02
     */
    @OperationLog(level = "信息", object = "告警项", operationType = "禁用")
    @RequestMapping("disableTrigger")
    public ResponseMessage disableTrigger(@RequestParam(value = "triggerid") String triggerid,
                                         @RequestParam(value = "status") String status,
                                          @RequestParam(value = "name") String name){
        // 更新告警项状态
        Map<String,Object> result = triggerService.updateTrigger(triggerid,status);

        ResponseMessage responseMessage = new ResponseMessage();
        result.put("log_objectName",name);
        result.put("log_description","禁用"+name);
        responseMessage.setContent(result);
        responseMessage.setStatus(true);
        return responseMessage;
    }

    /**
     * 根据id查询触发器的知识
     * @param body
     * @return
     */
    @RequestMapping("getKnowledgeByID")
    public ResponseMessage getKnowledgeByTriggerId(@RequestBody Map<String,Object> body){

        String triggerid = (String) body.get("triggerid");
        // 获取告警项信息
        Map<String,Object> result = triggerService.getTriggerByID(triggerid);
        JSONArray exp_arr = (JSONArray) result.get("result");
        JSONObject EXP = (JSONObject) exp_arr.get(0);
        Map<String,Object> exp_map = DateUtils.JsonToMap(EXP);
        String expression = (String) exp_map.get("expression");
        // 预处理之后的键值
        String after_exp = RegularMatcher.RE_Matcher(expression);
        // 查询绑定的知识
        List<Map<String, Object>> knowledgeBoundedList = knowledgeService.findBoundedKnowledgeBounded(after_exp);
        // 相似度查询关联知识
        List<Map<String, Object>> knowledgeList = knowledgeService.findKnowledgeByKey(after_exp);

        if (knowledgeBoundedList ==null && knowledgeList == null){
            Map<String,Object> resultMap = new HashMap<>();
            resultMap.put("knowledgeList",null);
            ResponseMessage responseMessage = new ResponseMessage();
            responseMessage.setContent(resultMap);
            responseMessage.setStatus(true);
            return responseMessage;
        }else {
            if (knowledgeBoundedList == null) {
                knowledgeBoundedList = knowledgeList;
            }else{
                knowledgeBoundedList.addAll(knowledgeList);
            }

            // 根据id属性去重
            List<Map<String,Object>> tmpList=new ArrayList<Map<String,Object>>();
            Set<String> keysSet = new HashSet<String>();
            for(Map<String, Object> collisionMap : knowledgeBoundedList){
                String keys =  collisionMap.get("id").toString();
                int beforeSize = keysSet.size();
                keysSet.add(keys);
                int afterSize = keysSet.size();
                if(afterSize == beforeSize + 1){
                    tmpList.add(collisionMap);
                }
            }
            Map<String,Object> resultMap = new HashMap<>();
            resultMap.put("knowledgeList",tmpList);
            ResponseMessage responseMessage = new ResponseMessage();
            responseMessage.setContent(resultMap);
            responseMessage.setStatus(true);
            return responseMessage;
        }
    }

    /**
     * 根据id查询具体键值
     * @param body
     * @return
     */
    @RequestMapping("getKeyByID")
    public ResponseMessage getKeyByID(@RequestBody Map<String,Object> body){
        // 告警项id
        String triggerid = (String) body.get("triggerid");
        Map<String,Object> result = triggerService.getTriggerByID(triggerid);
        JSONArray exp_arr = (JSONArray) result.get("result");
        JSONObject EXP = (JSONObject) exp_arr.get(0);
        // 利用工具类JSON转换为MAP
        Map<String,Object> exp_map = DateUtils.JsonToMap(EXP);
        // 获取键值表达式
        String expression = (String) exp_map.get("expression");
        // 利用工具类返回公共键值表达式
        String commonKey = RegularMatcher.RE_Matcher(expression);
        // 封装结果
        ResponseMessage responseMessage = new ResponseMessage();
        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put("key",expression);
        resultMap.put("commonKey",commonKey);
        if (result != null) {
            responseMessage.setContent(resultMap);
            responseMessage.setStatus(true);
        }else{
            responseMessage.setContent(null);
            responseMessage.setStatus(false);
        }
        return responseMessage;
    }

    /**
     * 根据主机id获取属所有高告警（优化后）
     * @param hostid
     * @return
     */
    @RequestMapping("getAllTriggersByHostid_new")
    public ResponseMessage getAllTriggerBtHostid_new(@RequestParam(value = "hostid") String hostid){
        String token = APIUtils.getToken();
        ResponseMessage responseMessage = new ResponseMessage();
        List<Map<String,Object>> triggers = triggerService.getAllTriggersByHostid_new(hostid,token);
        //封装返回结果
        ResponseMessage temp = packDataToResponseMessage(responseMessage, triggers);
        return temp;
    }

    /**
     * 获取所有的问题列表
     * @return
     */
    @RequestMapping("getAllTrigger_new")
    public ResponseMessage getAllTrigger_new(){
        // 1.从配置文件中读取固定模板的触发器和触发器原型
        List<Problem> problems_XML = triggerService.getAllTriggerByXML();
        // 2.从自定义触发器中读取触发器
        List<Problem> problem_com = triggerService.findComProblems();
        problems_XML.addAll(problem_com);
        List<String> commonKey = new ArrayList<>();
        List<Problem> problemList = problems_XML.stream().filter(// 过滤去重
                v -> {
                    boolean flag = !commonKey.contains(v.getCommonKey());
                    commonKey.add(v.getCommonKey());
                    return flag;
                }
        ).collect(Collectors.toList());
        ResponseMessage responseMessage = new ResponseMessage();
        Map<String, Object> result_map = new HashMap();
        result_map.put("problem_xml",problemList);
        responseMessage.setContent(result_map);
        return responseMessage;
    }

    /**
     * 根据简直获取问题数据
     * @return
     */
    @RequestMapping("getAllTriggerByKey_new")
    public ResponseMessage getAllTriggerByKey_new(@RequestParam(value = "searchText") String searchText){

        // 1.从配置文件中读取固定模板的触发器和触发器原型
        List<Problem> problems_XML = triggerService.getAllTriggerByXML();
        // 2.从自定义触发器中读取触发器
        List<Problem> problem_com = triggerService.findComProblems();
        problems_XML.addAll(problem_com);
        List<String> commonKey = new ArrayList<>();
        List<Problem> problemList = problems_XML.stream().filter(// 过滤去重
                v -> {
                    boolean flag = !commonKey.contains(v.getCommonKey());
                    commonKey.add(v.getCommonKey());
                    return flag;
                }
        ).collect(Collectors.toList());
        if (searchText == null) {
            ResponseMessage responseMessage = new ResponseMessage();
            Map<String, Object> result_map = new HashMap();
            result_map.put("problem_xml",problemList);
            responseMessage.setContent(result_map);
            return responseMessage;
        }else {
            List<Problem> resList = new ArrayList<>();
            for (Problem problem : problemList) {

                if (problem.getName().toLowerCase().contains(searchText.toLowerCase())){
                    resList.add(problem);
                }
            }
            ResponseMessage responseMessage = new ResponseMessage();
            Map<String, Object> result_map = new HashMap();
            result_map.put("problem_xml",resList);
            responseMessage.setContent(result_map);
            return responseMessage;
        }
    }
}
